package amd64

import (
	"fmt"
	"strconv"
)

var Debug string

type TextKindEnum int

const (
	NoAsm TextKindEnum = iota
	ADD
	ADDSS
	LEA
	MOV
	MOVSS
	SUB
	SUBSS
)

var (
	TextKindEnumStrMap = [...]string{
		NoAsm: "NoAsm",
		ADD:   "add",
		ADDSS: "addss",
		LEA:   "lea",
		MOV:   "mov",
		MOVSS: "movss",
		SUB:   "sub",
		SUBSS: "subss",
	}
)

func (enum TextKindEnum) String() string {
	return TextKindEnumStrMap[enum]
}

type DataKindEnum int

const (
	Int DataKindEnum = iota
	Float
	Auto
)

type RegEnum int64

const (
	NoReg RegEnum = iota
	RAX
	RBX
	RCX
	RDX
	RSP
	RBP
	RSI
	RDI
	R8
	R9
	R10
	R11
	R12
	R13
	R14
	R15

	Xmm0
	Xmm1
	Xmm2
	Xmm3
	Xmm4
	Xmm5
	Xmm6
	Xmm7
)

var (
	RegEnumStrMap = [...]string{
		NoReg: "no reg",
		RAX:   "rax",
		RBX:   "rbx",
		RCX:   "rcx",
		RDX:   "rdx",
		RSP:   "rsp",
		RBP:   "rbp",
		RSI:   "rsi",
		RDI:   "rdi",
		R8:    "R8",
		R9:    "r9",
		R10:   "r10",
		R11:   "r11",
		R12:   "r12",
		R13:   "r13",
		R14:   "r14",
		R15:   "r15",
		Xmm0:  "xmm0",
		Xmm1:  "xmm1",
		Xmm2:  "xmm2",
		Xmm3:  "xmm3",
		Xmm4:  "xmm4",
		Xmm5:  "xmm5",
		Xmm6:  "xmm6",
		Xmm7:  "xmm7",
	}
)

func (enum RegEnum) String() (s string) {
	if enum >= Xmm7 {
		s = strconv.Itoa(int(enum))
		return
	}
	return RegEnumStrMap[enum]
}

func (enum RegEnum) Asm() string {
	if enum == NoReg {
		panic("RegEnum零值无效")
	}
	return RegEnumStrMap[enum]
}

type TextTypeEnum int

const (
	TypeSrcMemDestReg TextTypeEnum = iota
	TypeSrcRegDestMem
	TypeSrcNumDestReg
	TypeSrcRegDestReg
	TypeSrcRegOffsetDestReg
	TypeSrcRegDestRegOffset
	TypeSrcNumDestRegOffset
	TypeSrcRegMemDestReg
	TypeSrcNumDestMem
	Labels
	MinMany
	ASSIGN
	StackAlloc
	StackFree
	StackVarMov
	Func
	AmExpr
	VarMov
	MaxMany
	MaxTextTypeEnum
)

var (
	TextTypeEnumStrMap [MaxTextTypeEnum]string = [MaxTextTypeEnum]string{
		TypeSrcMemDestReg:       "SrcMemDestReg",
		TypeSrcRegDestMem:       "SrcRegDestMem",
		TypeSrcNumDestReg:       "SrcNumDestReg",
		TypeSrcRegDestReg:       "SrcRegDestReg",
		TypeSrcRegOffsetDestReg: "SrcRegOffsetDestReg",
		TypeSrcRegDestRegOffset: "SrcRegDestRegOffset",
		TypeSrcNumDestRegOffset: "SrcNumDestRegOffset",
		TypeSrcRegMemDestReg:    "SrcRegMemDestReg",
		Labels:                  "Label",
		ASSIGN:                  "ASSIGN",
		StackAlloc:              "StackAlloc",
		StackFree:               "StackFree",
		StackVarMov:             "StackVarMov",
		Func:                    "Func",
	}
)

func (enum TextTypeEnum) String() string {
	return TextTypeEnumStrMap[enum]
}

type vrmTypeEnum int8

const (
	vrmNoType vrmTypeEnum = iota
	vrmx86
	vrmsse
)

var (
	vrmTypeEnumStrTable = [...]string{
		vrmNoType: "no type",
		vrmx86:    "x86",
		vrmsse:    "sse",
	}
)

func (enum vrmTypeEnum) String() string {
	if enum > 3 {
		return fmt.Sprint(int(enum))
	}
	return vrmTypeEnumStrTable[enum]
}

type VrmSizeEnum int8

const (
	vrmNoBit VrmSizeEnum = iota
	vrm64bit
	vrm32bit
	vrm16bit
	vrm8bit
	maxvrmSizeEnum
)

var (
	VrmSizeEnumStrTable = [...]string{
		vrmNoBit: "no bit",
		vrm64bit: "64bit",
		vrm32bit: "32bit",
		vrm16bit: "16bit",
		vrm8bit:  "8bit",
	}
)

func (enum VrmSizeEnum) String() string {
	return VrmSizeEnumStrTable[enum]
}
